home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / MacStarter (THINK C 5.0⁄6.0) / README next >
Text File  |  1994-01-31  |  20KB  |  188 lines

  1.  
  2. Note added Jan. 25, 1993:
  3.  
  4. I have heard from several people who had trouble using
  5. MacStarter with THINK C 6.0.  The problems seem to be caused
  6. by stricter type-checking of pointer types in version 6.0.
  7. They will go away if you turn off the "Check Pointer
  8. Types" option in the options box for THINK C (under the
  9. Edit Menu), but there turn out to be some actual errors
  10. (not just type problems) that should be corrected.
  11.  
  12. So, I have updated MacStarter to work with THINK C 6.0,
  13. as well as with version 5.0.  A few errors have also been
  14. corrected.  If you open MacStarter.π with THINK C 6.0,
  15. you will get a message that the project has to be converted.
  16. This is fine; just say OK.
  17.  
  18.  
  19.                          --David Eck
  20.  
  21. --------------------------------------------------------------------------------------------
  22.  
  23.                                              David Eck
  24.                                              Department of Mathematics
  25.                                              Hobart and William Smith Colleges
  26.                                              Geneva, NY   14456
  27.                                              E-mail:  eck@hws.bitnet 
  28.                                              Oct 12, 1992
  29.  
  30. Hi ! 
  31.  
  32.       Probably, most people who have programmed for the Macintosh at all seriously have their own "application shell," which includes the code common to most applications, and which can be filled in with code specific to a particular purpose to produce a working program.  Of course, THINK C and THINK Pascal come with a very complete application shell, the THINK Class Library.  Unfortunately, it is not easy to learn, and it is really TOO complete if all you want to do is knock together a quick-and-dirty, simple program.
  33.  
  34.      MacStarter.π is a simple application shell I have written for myself in THINK C 5.0.  Mostly, it provides the basic window behavior:  dragging, changing size, zooming, closing and vertical and horizontal scroll bars.  It uses a window class to provide these behaviors.  You create your own window by filling in the blanks in the definition of a subclass of the window class.  You don't really need to know anything in advance about object-oriented programming to use this shell.  I wrote the program this way because it allowed me to localize the changes that you need to make to one file, applicationProcs.c.  This file has functions that are called automatically when certain events occur.
  35.  
  36.      For example, when the user clicks the mouse on one of your windows (and if the click is not in a scroll bar, zoom box or some other part of the window that the shell handles itself), then a function called doContentClick in file applicationProcs.c is called.  All you have to do is fill in this function to say what the result of that click should be.  Similarly, menu commands are routed to appropriate functions in applicationProcs.c.
  37.  
  38.      Now, mind you, this shell is not anything fancy.  It doesn't provide capabilities even approaching those of the THINK class library.  Still, especially if you are just getting started in Mac programming, it can make it a lot easier to get a program working.  And it does provide a concrete example of what can be done with objects.  
  39.  
  40.      When you want to write a program with MacStarter, you should copy and rename applicationProcs.c and substitute the new file for applicationProcs.c in the project.  When you look at the file, you will find a lot of comments telling you how to proceed.  I have included three files that I created in this way:  scrollDemo.c, kaleidoSketch.c, and pentominos.c.   Each of these files can be used in MacStarter in place of applicationProcs.c to produce a working program.  (ScrollDemo is really just a demo, but KaleidoSketch and Pentominos are actually semi-interesting programs in their own right.)  Each of these files is well-commented.
  41.  
  42.      Of the remaining files in the folder, MacStarter.π.rsrc, globals-MacStarter.h, and globals-MacStarter.c are required by the application shell, and inputBoxes.h and inputBoxes.c provide some extra useful utilities.   These files are largely uncommented.  You don't need to understand how they work to use the shell.
  43.  
  44.     You are welcome to contact me if you have any problems with, or questions about, MacStarter (or, in fact, if you just want to let me know that you liked it).
  45.  
  46.     The rest of this README file describes some features that either didn't make it into the comments on applicationProcs.c or that are not covered very well there.
  47.  
  48.                                                          D. Eck
  49.  
  50.  
  51. ----------------------------------------------------------------
  52.  
  53. Utilities defined in inputBoxes.c:
  54.  
  55.      On the Mac, a lot of interaction with the user is done with dialog boxes.  The file inputBoxes.c provides a set of functions for such interaction.  Most of these functions have a first parameter of type "const Str255".  This parameter is a string that will appear in the dialog box as a message or prompt.  It must be a PASCAL style string, which is written in THINK C as a string beginning with \p, for example "\pPlease enter your name".
  56.      Many of the functions are defined to return type short.  These functions use a dialog box that includes a Cancel button.  The return value tells you whether the user dismissed the dialog box by clicking on the cancel button.  If so, the value returned will be 0; if not it will be 1.  This behavior allows you to use calls to these functions in if statements.  For example:   if (InputLongInt("\pHow big a window do you want?", n, 50,200)) { /* open a window of size n ... */ }.
  57.     To use these functions, you have to add inputBoxes.c to the project, and you should "#include inputBoxes.h" at the beginning of your applicationProcs file.  Here is a description of the functions available:
  58.  
  59. void TellUser(const Str255 message);
  60.   /* TellUser simply puts up a dialog box containing the string "message" and a single OK button. The box stays there until the user clicks on the OK button or presses return.  No information is returned. */
  61.  
  62. short AskUser(const Str255 question, short* answeredYes);
  63. void AskUserWithoutCancel(const Str255 question, short* answeredYes);
  64.   /* AskUser displays a box with the string "question" and three buttons labeled Yes, No and Cancel.  If the user clicks Cancel, the value returned by AskUser is 0.  If the user clicks on Yes or No, the value returned is 1, and in addition the value of the parameter answeredYes is set to 1 if the user clicked on Yes and to 0 if the user clicked on No.  You might use this as follows:  if (AskUser("\pSave before closing?",&response) && response) ...
  65.      AskUserWithoutCancel is similar except the dialog box has no Cancel button, so the user is forced to click on Yes or No. */
  66.  
  67. short InputString(const Str255 prompt, Str255 str, const short maxLength);
  68. short InputWord(const Str255 prompt, Str255 str, const short maxLength);
  69. short InputLongInt(const Str255 prompt, long* n, const long min, const long max);
  70. short InputDouble(const Str255 prompt, double* x, const double min, const double max);
  71.    /* InputString, InputWord, InputLongInt, and InputDouble provide dialog boxes that display the string "prompt" and a place for the user to type in a response.  The box also contains an OK and a Cancel button.  If the user does not press Cancel, the value typed in by the user is returned in the second parameter (str, n or x).  The remaining parameters are used to set limits on what values will be accepted from the user.
  72.    For InputString, you can specify the maximum length of the string you will accept for an answer, up to 255 characters.  The string can include any characters on the keyboard.  Note that the value returned is a Pascal-style string.   (If you put in an illegal value, such as 0, for maxLength, it will be changed to 255.)
  73.    InputWord is similar to InputString, except that the user will only be allowed to type in letters.
  74.    For InputLongInt, you can specify the minimum and maximum values you will accept.  If you specify min >= max  (for example, min=max=0), then any value typed in by the user will be acceptable.  The user will only be allowed to type in digits and, if the acceptable range includes negative numbers, minus signs.
  75.    InputDouble is similar to InputLongInt, except that the user can type in a real number, possibly with decimal point and exponential notation. */
  76.  
  77. FILE* OpenOldFile(Str255 fileName);
  78. FILE* OpenNewFile(const Str255 prompt, Str255 fileName);
  79.    /*  Standard C opens files with the function fopen.  The Mac interface uses standard file dialog boxes to allow the user to specify which file is to be opened.  OpenOldFile and OpenNewFile will perform both of these operations for you.  OpenOldFile presents the user with a standard old-file dialog box.  If the user selects a file, OpenOldFile will try to fopen that file for reading and, if it succeeds, return a pointer to the file.  You can use the pointer returned in fscanf in the usual way.  If the user cancels the dialog box, or if the file can't be opened for some reason, then OpenOldFile returns a value of 0.  (If an error occurs, the user will be informed of the error, so you don't have to worry about doing so.)  Thus, you will generally use this function like this:  if (OpenOldFile(fName)) ...
  80.     OpenNewFile is similar, except that the standard new-file dialog box is used, and the file is opened for writing.
  81.     Note that OpenNewFile has a prompt, but that OpenNewFile does not.  This is simply because the standard Mac old-file dialog box does not use a prompt.
  82.     Both functions return the name of the file selected by the user, just in case your program needs to know the name.  If you don't need the name, you can pass a value of 0 in the fileName parameter slot.  */
  83.  
  84. ------------------------------------------------------------------
  85.  
  86. The basic window class, xWindow (defined in globals-Macstarter):
  87.  
  88.     A window that you create in MacStarter is actually an "instance of the class" xWindow.  (A class is a structure that can contain functions as well as variables and that can be used as a basis for "subclasses" that contain everything in the parent class as well as any other stuff you want to throw in.)  An xWindow has all the standard Mac window behavior, but there is nothing displayed in the window.  When you define myWindow as a subclass of xWindow, it has all the behavior of an xWindow in addition to whatever else you program it to do.  Once you understand all that, you have begun to do object-oriented programming.
  89.     (By the way, the name "xWindow" was probably a bad choice in light of the completely unrelated X Window system.  I have this habit of giving names starting with x to things I write.  You see, xWindows are windows and they were made by Eck, so they are Eck's windows, right?  (Sorry.))
  90.     The following is the definition of the class xWindow, copied from globals-MacStarter.h, with a lot of comments added.  You will find a few useful things here that aren't mentioned in the file applicationProcs.c, along with a few remarks on objects in general.
  91.  
  92.  
  93. class xWindow : indirect {
  94.     /* The "indirect" just means that xWindows are represented by "Handles" rather than "Pointers."  You don't need to know what this means, except that you should avoid storing pointers to window data or passing such pointers as parameters, because such pointers can mysteriously and unexpectedly become invalid.  If you want to learn more, you will have to read about Macintosh memory management (in "Inside Macintosh" if you have no other choice). */
  95.  
  96. protected:
  97.    /* "protected" here means that the following declarations are visible to functions defined in xWindow itself and to functions defined in any of xWindow's subclasses.  However, they will be invisible from outside such functions.  That is, if win is an xWindow, then  win->features  will be legal in the definition of such a function, but not elsewhere.  There are two other types of visibility: public and private.  Public declarations are visible from anywhere.  Private declarations are visible in functions declared in xWindow, but NOT in functions declared in its sub-classes. */
  98.  
  99.    short features; 
  100.    int topScrollOffset,bottomScrollOffset;
  101.    int leftScrollOffset,rightScrollOffset;
  102.    int minH, maxH, minV, maxV;
  103.    int hLinesPerPage,vLinesPerPage;
  104.       /* the preceding 11 variables determine the behavior of the window and are described in the comment on function myWindow::SetDefaults in file applicationProcs.c */
  105.  
  106.    ControlHandle hScroll,vScroll;
  107.       /* hScroll and vScroll are handles to the window's scroll bars, if any.  There shouldn't be anything for you to do with them. */
  108.  
  109.    WindowPtr theWindow;
  110.       /* theWindow is the standard Macintosh representation for the window.  You should treat this as a read-only variable.  The most likely uses are  SetPort(theWindow) to set up for drawing in the window, and theWindow->portRect to find the current size of the window.  Note that SetPort(theWindow) is already done for you before the procedures doKey, doRedraw, and doContentClick are called. */
  111.  
  112.    xWindow *nextWindow;
  113.        /* The current opened windows are kept in a linked list.  nextWindow is the link to the next window in the list.  The beginning of the list is stored in the global variable xWindowList.  See function ApplicationIdle in file pentominos.c for an example of how this can be used. */
  114.  
  115.  
  116. public:  /* available for use anywhere */
  117.  
  118.    virtual void OpenInRect(Str255 title, int left, int top, int right, int bottom);
  119.    void OpenFullScreen(Str255 title);
  120.    void Open(Str255 title);
  121.         /* There are three different functions for opening a window.  The first is declared "virtual".  This means that it can be redefined in a sub-class of xWindow.  The other two cannot be redefined; they are simply translated into calls to OpenInRect in any case.  Note that you must "new" the window variable before using any of these procedures.  Also note that the title must be a pascal-style string.  For example,
  122.                     xWindow win;
  123.                     win = new xWindow;
  124.                     win->OpenInRect("\pEmpty Window",10,40,200,150);
  125. See also the comments on functions OpenInRect and DoNewCommand in file applicationProcs.c.  */
  126.  
  127.    virtual short Close(void);
  128.        /* Call this to close a window; See comments on function Close in file applicationProcs.c */
  129.  
  130.    static int Window2XWindow(WindowPtr win, xWindow** xWin);
  131.        /*  The Mac deals with windows's in terms of WindowPtrs.  In particular, if you use the toolbox functions FrontWindow and FindWindow, they give you back a WindowPtr.  The function xWindow::Window2XWindow(win,&xwin) will convert a WindowPtr win to the corresponding xWindow xwin such that xwin->theWindow == win.  If there is no such xWindow, the value returned by Window2XWindow will be 0.  See functions UpdateMenus and DoFileMenu in aplicationProcs.c for examples of the use of this function. 
  132.      (Note that this function is referred to as xWindow::Window2XWindow, not simply as Window2XWindow.  The designation "static" means that this function is considered part of the class itself rather than of the individual xWindows.  It is declared here, rather than as a separate function, so that it can have access to the protected variable nextWindow.  In C++, by the way, I would have been able to declare Window2XWindow to be a "friend" of the xWindow class, rather than a static member.  Also, in C++, in case you are interested, all the Open procedures would have been "constructors", eliminating the need to "new" a window before opening it.) */
  133.  
  134.    void doEvent(void);
  135.         /* This should not really be public at all.  It is called by function main() to process an event directed at this window.  Ignore it.  */
  136.  
  137.  protected:  /* for use in subclass functions */
  138.  
  139.    virtual void SetDefaults(void);
  140.    virtual void doKey(char ch);
  141.    virtual void doContentClick(Point localPt);
  142.    virtual void adjustToNewSize(void);
  143.    virtual void doRedraw(Rect* badRect);
  144.    virtual void doActivate(int active);
  145.    virtual void doHScroll(int dh);
  146.    virtual void doVScroll(int dv);
  147.        /* These 9 functions can be redefined in a subclass of xWindow, such as myWindow.  They are adequately described in file applicationProcs.c */
  148.  
  149.       /* You should know about the existence of the following 13 functions, because they might be useful to you as you are "filling-in" the definition of myWindow in applicationProcs.c.  Note that these are not "virtual."  You will never have to rewrite them.  They are provided as utilities for you to use. */
  150.  
  151.    void GetTitle(Str255 name);
  152.    void SetTitle(Str255 name);
  153.       /* GetTitle and SetTile allow you to read and set the title displayed in the title bar of the window.  Note that the title is a Pascal-style string.  Since you also provide a title when you first open the window, you will only need SetTitle if you want to change that title. */
  154.  
  155.    void ForceRedraw(Rect *badRect);
  156.       /* As noted in the comments on doRedraw in file applicationProcs.c, you should generally use that function to draw the contents of a window.   If at some point the window or part of it needs to be redrawn, you might be tempted to call doRedraw directly.  Probably a bad idea.  doRedraw requires some set-up before it is called.  You should call ForceRedraw instead, which will arrange to have doRedraw called correctly.  If you call ForceRedraw(0), the whole window will be scheduled to be redrawn at the next opportunity  (i.e, next time through the event loop).  If you want to specify that only a certain rectangle is bad, pass that rectangle as a parameter.  It will be handed as the badRect parameter to function doRedraw.  
  157.      Note that you can directly draw into the window in functions doKey and doContentClick.  Otherwise if you want to draw into the window in "real time", you should first set up the drawing port with a call to SetPort.  See function putPiece in file pentominos.c for an example.
  158.      (FYI, ForceRedraw generates an "update event" for the window by calling the Mac toolbox function InvalRect.) */
  159.  
  160.    int GetHVal(void);
  161.    int GetVVal(void);
  162.    void SetHVal(int val);
  163.    void SetVVal(int val);
  164.    int GetHMax(void);
  165.    int GetVMax(void);
  166.    void SetHMax(int val);
  167.    void SetVMax(int val);
  168.    void SetHLinesPerPage(short hLines);
  169.    void SetVLinesPerPage(short vLines);
  170.         /* These 10 functions have to do with the scroll bars.  If you have scroll bars, you will need to read their values in order to know what to draw in the window.  You can get the value of the horizontal or vertical scroll bars by calling GetHVal() or GetVVal().  The value will be a number from 0 up to a maximum specified by SetHMax() or SetVMax().  If the maximum value is set to 0, as it is by default, the scroll bar will be inactive.  You can read the current maximums with GetHMax() and GetVMax().  SetHVal() and SetVVal will ordinarily be called only by the system, when the user clicks on a scroll bar.  SetHLinesPerPage and SetVLinesPerPage determine the relation between what happens when the user clicks on an arrow and when he clicks in the gray area of a scroll bar.  All the "Set" functions in this group are used most often in adjustToNewSize().  See the comments on that function in file applicationProcs.c for more information.  The file scrollDemo.c demonstrates the use of some of these scroll bar functions. */
  171.  
  172. private:  
  173.  
  174.     /* This "private" part of the xWindow structure is completely hidden, so you can ignore it as you define an use the subclass myWindow.  The functions here implement the basic window functions, except for the "destructor" ~xWindow.  This destructor is declared private simply to make it impossible for any xWindow to be deleted except through xWindow::Close.  Another interesting feature is the "static" procedure ContinuousScroll, which is used when the user holds down the mouse in a scroll bar.  This is declared as a static class method so that it can have access to the scrolling xWindow's variables. */
  175.  
  176.    ~xWindow(void);
  177.    void doBasicOpen(Str255 title, int left, int top, int right, int bottom);
  178.    void doClick(Point globalPt);
  179.    void doDrag(Point globalPt);
  180.    void doZoom(short partNum);
  181.    void doGrow(Point globalPt);
  182.    void doUpdate(void);
  183.    static pascal void ContinuousScroll(ControlHandle theControl, short partNum);
  184.  
  185.  };
  186.  
  187.  
  188.